/****************************************************************************
 * Copyright (C) 2011
 * by Dimok
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 ***************************************************************************/
#include "ThemeDownloader.h"
#include "ThemeInfosWindow.h"
#include "UnpackThemeTask.h"
#include "ThemeDownloadTask.h"
#include "SpiffyListTask.h"
#include "ThemeThumbsTask.h"
#include "../CTheme.h"
#include "../../Prompts/PromptWindows.h"
#include "../../Prompts/ProgressWindow.h"
#include "../../FileOperations/fileops.h"
#include "../../Controls/Application.h"

ThemeDownloader::ThemeDownloader()
	: FlyingButtonsMenu()
{
	ThemeList = NULL;
	
	ThemeListURL = "http://wii.spiffy360.com/themes.php?xml=1&category=8&adult=";
	if(Settings.GodMode)
		ThemeListURL += "1";
	else
		ThemeListURL += "0";

	buttonImgData = Resources::GetImageData("theme_box.png");
	
	urlTxt = new GuiText(tr( "Themes by www.spiffy360.com" ), thInt("22 - theme_menu spiffy text size"), thColor("r=255 g=255 b=255 a=255 - theme_menu spiffy text color"));
	urlTxt->SetAlignment(thAlign("right - theme_menu spiffy text align hor") | thAlign("bottom - theme_menu spiffy text align ver"));
	urlTxt->SetPosition(thInt("-30 - theme_menu spiffy text pos x"), thInt("-17 - theme_menu spiffy text pos y"));
	Append(urlTxt);

	for(int i = 0; i < 4; ++i)
		ThemePreviews[i] = NULL;
	
	SetupMainButtons();
}

ThemeDownloader::~ThemeDownloader()
{
	Resources::Remove(buttonImgData);
	Remove(urlTxt);

	delete urlTxt;
	if(ThemeList)
		delete ThemeList;
	
	for(int i = 0; i < 4; ++i)
	{
		if(ThemePreviews[i])
			delete ThemePreviews[i];
	}
}

void ThemeDownloader::SetupMainButtons()
{
	if(!NetworkInitPrompt())
		return;
	
	SpiffyListTask *task = new SpiffyListTask(ThemeListURL);
	
	while(task->IsRunning())
		Application::Instance()->updateEvents();
	
	ThemeList = task->GetThemeList();
	delete task;
	
	if(ThemeList == NULL)
		return;
	
	for(int i = 0; i < ThemeList->GetThemeCount(); ++i)
	{
		ThemeDownloader::SetMainButton(i, ThemeList->GetThemeTitle(i), buttonImgData, NULL);
	}
	
	SetPageIndicators();
}

void ThemeDownloader::SetMainButton(int position, const char * ButtonText, GuiImageData * imageData, GuiImageData * themeImg)
{
	if(position < (int) mainButton.size())
	{
		delete mainButtonImg[position];
		delete mainButtonImgOver[position];
		delete mainButtonTxt[position];
		delete mainButton[position];
	}
	else
	{
		mainButtonImg.resize(position+1);
		mainButtonImgOver.resize(position+1);
		mainButtonTxt.resize(position+1);
		mainButton.resize(position+1);
	}

	mainButtonImg[position] = new GuiImage(imageData);
	mainButtonImgOver[position] = new GuiImage(themeImg);
	mainButtonImgOver[position]->SetScale(0.4);
	mainButtonImgOver[position]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	mainButtonImgOver[position]->SetPosition(0, -45);
	
	mainButtonTxt[position] = new GuiText(ButtonText, thInt("18 - theme_menu mainbutton theme_title text size"), thColor("r=0 g=0 b=0 a=255 - theme_menu mainbutton theme_title text color"));
	mainButtonTxt[position]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	mainButtonTxt[position]->SetPosition(0, 10);
	mainButtonTxt[position]->SetMaxWidth(imageData->GetWidth() - 10, DOTTED);

	mainButton[position] = new GuiButton(imageData->GetWidth(), imageData->GetHeight());
	mainButton[position]->SetAlignment(ALIGN_LEFT | ALIGN_TOP);
	mainButton[position]->SetImage(mainButtonImg[position]);
	mainButton[position]->SetImageOver(mainButtonImg[position]);
	mainButton[position]->SetSoundOver(btnSoundOver);
	mainButton[position]->SetSoundClick(btnSoundClick);
	mainButton[position]->SetIcon(mainButtonImgOver[position]);
	mainButton[position]->SetLabel(mainButtonTxt[position]);
	mainButton[position]->SetTrigger(trigA);
	mainButton[position]->SetEffectGrow();
	mainButton[position]->Clicked.connect(this, &ThemeDownloader::OnMainButtonClick);
	mainButton[position]->StateChanged.connect(this, &ThemeDownloader::OnStateChange);
	
	switch(position % 4)
	{
		case 0:
			mainButton[position]->SetPosition(90, 75);
			break;
		case 1:
			mainButton[position]->SetPosition(340, 75);
			break;
		case 2:
			mainButton[position]->SetPosition(90, 230);
			break;
		case 3:
			mainButton[position]->SetPosition(340, 230);
			break;
		default:
			break;
	}
}

void ThemeDownloader::AddMainButtons()
{
	for(u32 i = 0; i < mainButton.size(); ++i)
		Remove(mainButton[i]);
	
	int firstItem = currentPage*4;
	
	ThemeThumbsTask * task = new ThemeThumbsTask(ThemeList, firstItem);
	
	while(task->IsRunning())
		Application::Instance()->updateEvents();
	
	int n = 0;
	for(int i = firstItem; i < (int) mainButton.size() && i < firstItem+4; ++i)
	{
		mainButtonImgOver[i]->SetImage(task->GetThumbData(n));
		Append(mainButton[i]);
		n++;
	}
	
	delete task;
	
	AddPageIndicators();
}

void ThemeDownloader::OnStateChange(GuiElement *sender, int state, int stateChan UNUSED)
{
	int FirstItem = currentPage*4;
	for(int i = FirstItem; i < (int) mainButton.size() && i < FirstItem+4; ++i)
	{
		if(sender == mainButton[i])
		{
			if(state == STATE_DEFAULT)
				mainButtonTxt[i]->SetPosition(0, 10);
			else
				mainButtonTxt[i]->SetPosition(0, 3);
			
			break;
		}
	}
}

void ThemeDownloader::OnMainButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	//FlyingButtonsMenu::OnMainButtonClick(sender, pointer, p);
	
	for(u32 i = 0; i < mainButton.size(); ++i)
	{
		if(sender != mainButton[i])
			continue;
		
		ThemeInfosWindow * Infos = new ThemeInfosWindow(ThemeList->GetThemeTitle(i),
														ThemeList->GetThemeAuthor(i),
														ThemeList->GetThemeVersion(i),
														ThemeInfosWindow::DOWNLOAD);
		
		int choice = -1;
		while((choice = Infos->GetChoice()) < 0)
			Application::Instance()->updateEvents();
		
		Infos->SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
		while(Infos->IsAnimated())
			Application::Instance()->updateEvents();
		
		Application::Instance()->PushForDelete(Infos);
		Application::Instance()->updateEvents();
		
		if(choice)
		{
			if(WindowPrompt(tr( "Do you want to download this theme?" ), ThemeList->GetThemeTitle(i), tr( "Yes" ), tr( "Cancel" )))
				DownloadTheme(i);
		}
		
		break;
	}
}

void ThemeDownloader::DownloadTheme(int ind)
{
	const char *url = ThemeList->GetDownloadLink(ind);
	if (!url)
		return;
	
	if(!CreateSubfolder(Settings.ThemePath))
	{
		ShowError(tr("Can't create path: %s"), Settings.ThemePath);
		return;
	}

	ThemeDownloadTask *download = new ThemeDownloadTask(url);
	
	while(download->IsRunning())
		Application::Instance()->updateEvents();
	
	int succes = download->Succes();
	delete download;
	if(!succes)
		return;
	
	char filepath[300];
	snprintf(filepath, sizeof(filepath), "%s/TempTheme.zip", Settings.ThemePath);
	
	ZipFile * zipfile = new ZipFile(filepath); 
	
	UnpackThemeTask *task = new UnpackThemeTask(ThemeList->GetThemeTitle(ind), Settings.ThemePath, zipfile);
	
	while(task->IsRunning())
		Application::Instance()->updateEvents();
	
	std::string Filename = task->GetThemeFileName();
	delete task;
	
	if (!WindowPrompt(tr( "Successfully extracted theme." ), tr( "Do you want to apply it now?" ), tr( "Yes" ), tr( "No" )))
		return;

	if(Filename.size() == 0)
	{
		WindowPrompt(tr( "ERROR: Can't set up theme." ), tr( "The .them file was not found in the zip." ), tr( "OK" ));
		return;
	}
	
	char real_themepath[1024];
	snprintf(real_themepath, sizeof(real_themepath), "%s/%s", Settings.ThemePath, Filename.c_str());
	
	Application::Instance()->setReload(Application::RELOAD_THEME);
	
	if (Theme::Load(real_themepath))
	{
		snprintf(Settings.Theme, sizeof(Settings.Theme), real_themepath);
		Settings.Save();
	}
	else
		Theme::Load(Settings.Theme);
	
	ThemeReloadRequest();
}
